import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import csv
import os
import tempfile
import shutil
import json
from PIL import Image, ImageTk, ImageGrab
import threading
import keyboard
from datetime import datetime


class ScreenshotTool:
    def __init__(self, root):
        self.root = root
        self.root.title("截图工具 v1.0")
        self.root.geometry("1200x700")
        self.root.configure(bg="#f0f0f0")

        # 初始化变量
        self.data = []
        self.current_index = 0
        self.config_file = "screenshot_tool_config.json"
        self.screenshot_dir = os.path.join(tempfile.gettempdir(), "screenshot_tool")
        self.config = self.load_config()

        # 创建截图目录
        if not os.path.exists(self.screenshot_dir):
            os.makedirs(self.screenshot_dir)

        # 创建主框架
        self.create_widgets()

        # 加载配置
        self.load_settings()

        # 设置窗口关闭事件
        self.root.protocol("WM_DELETE_WINDOW", self.on_closing)

    def create_widgets(self):
        # 主框架
        main_frame = ttk.Frame(self.root)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        # 左侧数据表格
        left_frame = ttk.LabelFrame(main_frame, text="数据列表")
        left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5)

        # 表格列
        columns = ("file", "tips", "screenshot_status", "preview")

        # 创建表格
        self.tree = ttk.Treeview(left_frame, columns=columns, show="headings", height=15)

        # 设置列标题
        self.tree.heading("file", text="文件名")
        self.tree.heading("tips", text="提示信息")
        self.tree.heading("screenshot_status", text="截图状态")
        self.tree.heading("preview", text="图片预览")

        # 设置列宽
        self.tree.column("file", width=200)
        self.tree.column("tips", width=200)
        self.tree.column("screenshot_status", width=100)
        self.tree.column("preview", width=300)

        # 添加滚动条
        scrollbar = ttk.Scrollbar(left_frame, orient=tk.VERTICAL, command=self.tree.yview)
        self.tree.configure(yscroll=scrollbar.set)

        # 布局
        self.tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        # 右侧操作区
        right_frame = ttk.LabelFrame(main_frame, text="截图操作")
        right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, padx=5, pady=5, ipadx=10, ipady=10)

        # 当前文件信息
        ttk.Label(right_frame, text="当前文件:").grid(row=0, column=0, sticky="w", pady=(10, 5))
        self.current_file_var = tk.StringVar()
        self.current_file_label = ttk.Label(right_frame, textvariable=self.current_file_var, font=("Arial", 10, "bold"))
        self.current_file_label.grid(row=0, column=1, sticky="w", pady=(10, 5))

        ttk.Label(right_frame, text="提示信息:").grid(row=1, column=0, sticky="w", pady=5)
        self.tips_var = tk.StringVar()
        self.tips_label = ttk.Label(right_frame, textvariable=self.tips_var, font=("Arial", 10))
        self.tips_label.grid(row=1, column=1, sticky="w", pady=5)

        # 截图按钮
        self.screenshot_btn = ttk.Button(right_frame, text="开始截图", command=self.start_screenshot, state=tk.DISABLED)
        self.screenshot_btn.grid(row=2, column=0, columnspan=2, pady=20, ipadx=20, ipady=10)

        # 图片预览
        ttk.Label(right_frame, text="图片预览:").grid(row=3, column=0, columnspan=2, sticky="w", pady=(20, 5))

        self.preview_frame = ttk.Frame(right_frame, borderwidth=1, relief="solid")
        self.preview_frame.grid(row=4, column=0, columnspan=2, pady=5, sticky="nsew")

        self.preview_label = ttk.Label(self.preview_frame)
        self.preview_label.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        # 设置空图片
        self.empty_image = Image.new("RGB", (400, 300), color="#f0f0f0")
        self.empty_photo = ImageTk.PhotoImage(self.empty_image)
        self.preview_label.configure(image=self.empty_photo)

        # 导航按钮
        nav_frame = ttk.Frame(right_frame)
        nav_frame.grid(row=5, column=0, columnspan=2, pady=20)

        self.prev_btn = ttk.Button(nav_frame, text="上一条", command=self.prev_item, state=tk.DISABLED)
        self.prev_btn.pack(side=tk.LEFT, padx=10)

        self.next_btn = ttk.Button(nav_frame, text="下一条", command=self.next_item, state=tk.DISABLED)
        self.next_btn.pack(side=tk.LEFT, padx=10)

        # 底部功能区
        bottom_frame = ttk.Frame(main_frame)
        bottom_frame.pack(fill=tk.X, padx=5, pady=10)

        # 导入按钮
        import_btn = ttk.Button(bottom_frame, text="导入数据", command=self.import_data)
        import_btn.pack(side=tk.LEFT, padx=5)

        # 快捷键设置
        shortcut_frame = ttk.LabelFrame(bottom_frame, text="截图快捷键")
        shortcut_frame.pack(side=tk.LEFT, padx=10)

        self.shortcut_var = tk.StringVar()
        self.shortcut_var.set("F11")
        shortcut_entry = ttk.Entry(shortcut_frame, textvariable=self.shortcut_var, width=10)
        shortcut_entry.pack(side=tk.LEFT, padx=5, pady=5)

        set_shortcut_btn = ttk.Button(shortcut_frame, text="设置", command=self.set_shortcut)
        set_shortcut_btn.pack(side=tk.LEFT, padx=5)

        # 窗口置顶
        self.topmost_var = tk.BooleanVar()
        topmost_check = ttk.Checkbutton(bottom_frame, text="窗口置顶", variable=self.topmost_var,
                                        command=self.toggle_topmost)
        topmost_check.pack(side=tk.LEFT, padx=10)

        # 状态栏
        self.status_var = tk.StringVar()
        self.status_var.set("就绪")
        status_bar = ttk.Label(self.root, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W)
        status_bar.pack(side=tk.BOTTOM, fill=tk.X)

        # 配置网格布局
        right_frame.columnconfigure(1, weight=1)
        right_frame.rowconfigure(4, weight=1)

    def import_data(self):
        file_path = filedialog.askopenfilename(
            title="选择数据文件",
            filetypes=[("CSV文件", "*.csv"), ("所有文件", "*.*")]
        )

        if not file_path:
            return

        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                reader = csv.DictReader(f)
                self.data = list(reader)

                # 检查数据格式
                if 'file' not in self.data[0] or 'tips' not in self.data[0]:
                    messagebox.showerror("错误", "CSV文件必须包含 'file' 和 'tips' 列")
                    return

                # 加载截图状态
                self.load_screenshot_status()

                # 清空表格
                for item in self.tree.get_children():
                    self.tree.delete(item)

                # 填充表格
                for i, row in enumerate(self.data):
                    filename = row['file']
                    tips = row['tips']

                    # 检查截图状态
                    screenshot_path = os.path.join(self.screenshot_dir, filename)
                    status = "已截图" if os.path.exists(screenshot_path) else "未截图"

                    # 插入表格
                    self.tree.insert("", "end", values=(filename, tips, status, ""))

                    # 如果存在截图，显示预览
                    if os.path.exists(screenshot_path):
                        self.update_preview(i, screenshot_path)

                # 启用按钮
                self.screenshot_btn["state"] = tk.NORMAL
                self.prev_btn["state"] = tk.NORMAL
                self.next_btn["state"] = tk.NORMAL

                # 显示第一条
                self.current_index = 0
                self.show_current_item()

                self.status_var.set(f"成功导入 {len(self.data)} 条数据")

        except Exception as e:
            messagebox.showerror("错误", f"导入数据失败: {str(e)}")

    def load_screenshot_status(self):
        # 检查截图状态
        for row in self.data:
            filename = row['file']
            screenshot_path = os.path.join(self.screenshot_dir, filename)
            if os.path.exists(screenshot_path):
                row['screenshot_status'] = "已截图"
            else:
                row['screenshot_status'] = "未截图"

    def show_current_item(self):
        if not self.data:
            return

        row = self.data[self.current_index]
        self.current_file_var.set(row['file'])
        self.tips_var.set(row['tips'])

        # 更新预览
        screenshot_path = os.path.join(self.screenshot_dir, row['file'])
        if os.path.exists(screenshot_path):
            self.show_preview(screenshot_path)
        else:
            self.preview_label.configure(image=self.empty_photo)

        # 更新表格选中项
        children = self.tree.get_children()
        if children:
            self.tree.selection_set(children[self.current_index])
            self.tree.see(children[self.current_index])

    def start_screenshot(self):
        if not self.data:
            return

        # 隐藏窗口
        self.root.withdraw()
        self.status_var.set("窗口已隐藏，请使用鼠标选择截图区域...")

        # 在单独的线程中执行截图
        threading.Thread(target=self.capture_screenshot, daemon=True).start()

    def capture_screenshot(self):
        # 等待用户截图
        screenshot = ImageGrab.grab()

        # 显示窗口
        self.root.after(0, self.root.deiconify)

        if screenshot:
            # 保存截图
            filename = self.data[self.current_index]['file']
            screenshot_path = os.path.join(self.screenshot_dir, filename)
            screenshot.save(screenshot_path)

            # 更新状态
            self.data[self.current_index]['screenshot_status'] = "已截图"

            # 更新表格
            children = self.tree.get_children()
            self.tree.item(children[self.current_index], values=(
                self.data[self.current_index]['file'],
                self.data[self.current_index]['tips'],
                "已截图",
                ""
            ))

            # 显示预览
            self.root.after(0, lambda: self.show_preview(screenshot_path))

            # 移动到下一条
            self.root.after(0, self.next_item)

            self.status_var.set(f"截图已保存: {filename}")
        else:
            self.status_var.set("截图已取消")

    def show_preview(self, image_path):
        try:
            image = Image.open(image_path)
            # 调整大小以适应预览区域
            width, height = image.size
            max_width = 400
            max_height = 300

            if width > max_width or height > max_height:
                ratio = min(max_width / width, max_height / height)
                new_width = int(width * ratio)
                new_height = int(height * ratio)
                image = image.resize((new_width, new_height), Image.LANCZOS)

            photo = ImageTk.PhotoImage(image)
            self.preview_label.configure(image=photo)
            self.preview_label.image = photo  # 保持引用
        except Exception as e:
            messagebox.showerror("错误", f"无法加载图片: {str(e)}")

    def update_preview(self, index, image_path):
        try:
            image = Image.open(image_path)
            # 创建小缩略图
            image.thumbnail((100, 100), Image.LANCZOS)
            photo = ImageTk.PhotoImage(image)

            # 更新表格中的预览
            children = self.tree.get_children()
            if index < len(children):
                self.tree.item(children[index], values=(
                    self.data[index]['file'],
                    self.data[index]['tips'],
                    self.data[index]['screenshot_status'],
                    ""
                ))
                self.tree.set(children[index], "preview", "")
                self.tree.image = photo  # 保持引用
        except:
            pass

    def prev_item(self):
        if self.data and self.current_index > 0:
            self.current_index -= 1
            self.show_current_item()

    def next_item(self):
        if self.data and self.current_index < len(self.data) - 1:
            self.current_index += 1
            self.show_current_item()

    def set_shortcut(self):
        new_shortcut = self.shortcut_var.get()
        if new_shortcut:
            self.config['shortcut'] = new_shortcut
            self.save_config()
            messagebox.showinfo("成功", f"截图快捷键已设置为: {new_shortcut}")

    def toggle_topmost(self):
        topmost = self.topmost_var.get()
        self.root.attributes("-topmost", topmost)
        self.config['topmost'] = topmost
        self.save_config()

    def load_config(self):
        config = {
            "shortcut": "F11",
            "topmost": False,
            "screenshot_dir": os.path.join(tempfile.gettempdir(), "screenshot_tool")
        }

        try:
            if os.path.exists(self.config_file):
                with open(self.config_file, 'r') as f:
                    return json.load(f)
        except:
            pass

        return config

    def save_config(self):
        try:
            with open(self.config_file, 'w') as f:
                json.dump(self.config, f, indent=2)
        except:
            pass

    def load_settings(self):
        # 加载快捷键
        self.shortcut_var.set(self.config.get('shortcut', 'F11'))

        # 加载置顶设置
        topmost = self.config.get('topmost', False)
        self.topmost_var.set(topmost)
        self.root.attributes("-topmost", topmost)

    def on_closing(self):
        self.save_config()
        self.root.destroy()


def main():
    root = tk.Tk()
    app = ScreenshotTool(root)
    root.mainloop()


if __name__ == "__main__":
    main()